package com.bear.fastrepair.mvvm.data.login

import com.bear.fastrepair.entity.EmployeeLoginBody
import com.bear.fastrepair.entity.ManagerLoginInfo
import com.bear.fastrepair.entity.ResponseInfo
import com.bear.fastrepair.http.api.ManagerService
import com.bear.fastrepair.http.api.VerificationCodeService
import com.bear.fastrepair.http.api.employee.EmployeeService2
import com.bear.fastrepair.http.client.RetrofitManager
import com.bear.fastrepair.mvvm.data.MainDataSource
import com.bear.fastrepair.mvvm.data.Result
import com.bear.fastrepair.utils.*
import okhttp3.Headers
import java.io.IOException

/**
 * Class that handles authentication w/ login credentials and retrieves user information.
 */
class LoginDataSource {
    private val main = MainDataSource()
    private var verificationHeaders: Headers? = null

    suspend fun login(
        username: String,
        password: String,
        loginType: Int,
        verificationCode: String?
    ): Result<ResponseInfo> {
        return try {
            when (loginType) {
                TYPE_EMPLOYEE -> RetrofitManager.getServiceSetCookie(
                    URL_MOBILE,
                    EmployeeService2::class.java,
                    verificationHeaders
                ).login(
                    EmployeeLoginBody(username, password, verificationCode)
                )
                TYPE_MANAGER -> RetrofitManager.getServiceSetCookie(
                    URL,
                    ManagerService::class.java,
                    verificationHeaders
                ).managerLogin(
                    ManagerLoginInfo(username, password, verificationCode)
                )
                else -> throw Throwable("no such login type")
            }.let {
                if (it.code == 0) {
                    SharedPreferencesHelper.let { sp ->
                        sp.putInfo(ACCOUNT_TOKEN_KEY, it.data)
                        sp.putInfo(ACCOUNT_KEY, username)
                        sp.putInfo(PASSWORD_KEY, password)
                        sp.putInfo(ACCOUNT_TYPE_KEY, loginType)
                    }
                    Result.Success(it)
                } else Result.Error(data = it)
            }
        } catch (e: Throwable) {
            Result.Error(IOException("Error logging in", e))
        }
    }

    fun logout() {
        // TODO: revoke authentication
    }

    suspend fun getVerificationCode() =
        RetrofitManager.getService(URL, VerificationCodeService::class.java) {
            verificationHeaders = it
        }.getVerificationCode()

    suspend fun getPersonalInfo() = main.getEmployeePersonalInfo()
}